package com.jpaAutoProcess;

import com.jpaAutoProcess.selectKernel.KernelClass;
import com.jpaAutoProcess.utils.SqlUtils;
import com.jpaAutoProcess.utils.parseParamCondition.RequirParametersAndConditions;
import com.jpaAutoProcess.utils.ParamConditionBO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author cc
 * @date 2022/6/18 18:34
 * @Description : 自动分页
 */

public class AutoPage {

    /**
     *
     * @param select (select xxx ,xxx From 注意：尽量别写select *)
     * @param orderBy 根据哪个个排序 (与字段名对应)
     * @param from 条件 (from xxx )
     * @param order 倒序desc 还是顺序asc (与字段名对应)
     * @param ParametersAndConditionsMap 使用：RequirParametersAndConditions.getInstance() 需要判断的字段和判断条件 类型为AutoPageParametersConditionsMap 直接RequirParametersAndConditions.getInstance()
     * @param pageable 分页相关参数
     * @param entityManager sql执行
     * @param classtype 要转换成什么类型
     **/
    public static Page AutoPage(String select, String from, String orderBy, String order, RequirParametersAndConditions<ParamConditionBO, Object> ParametersAndConditionsMap, Pageable pageable, EntityManager entityManager, Class<?> classtype){
        return AutotablePortal(select,from,orderBy,order,ParametersAndConditionsMap,pageable,entityManager,classtype);
    }

    /**
     * @param select (select xxx ,xxx From 注意：尽量别写select *)
     * @param from 条件 (from xxx )
     * @param ParametersAndConditionsMap 使用：RequirParametersAndConditions.getInstance() 需要判断的字段和判断条件 类型为RequirParametersAndConditions
     * @param pageable 分页相关参数
     * @param entityManager sql执行
     * @param classtype 要转换成什么类型
     **/
    public static Page AutoPage(String select, String from, RequirParametersAndConditions<ParamConditionBO, Object> ParametersAndConditionsMap, Pageable pageable, EntityManager entityManager, Class<?> classtype){
        return AutotablePortal(select,from,null,null,ParametersAndConditionsMap,pageable,entityManager,classtype);
    }

    /**
     *
     * @author: C.c
     * @date: 2022-06-07 11:41
     * @description:  自动分页核心
     *
     * @param select (select xxx ,xxx From 注意：尽量别写select *)
     * @param orderBy 根据哪个个排序 (与字段名对应)
     * @param from 条件 (from xxx )
     * @param order 倒序desc 还是顺序asc (与字段名对应)
     * @param databaseParameters 类型为RequirParametersAndConditions 直接RequirParametersAndConditions.getInstance()
     * @param pageable 分页相关参数
     * @param entityManager sql执行
     * @param classtype 要转换成什么类型
     **/
    private static Page AutotablePortal(String select, String from, String orderBy, String order, RequirParametersAndConditions<ParamConditionBO, Object> databaseParameters, Pageable pageable, EntityManager entityManager, Class<?> classtype){
        Query countQuery = null;
        StringBuilder selectSql = new StringBuilder().append(select);
        StringBuilder fromsql = new StringBuilder().append(from);
        StringBuilder wheresql = new StringBuilder();
        StringBuilder countSql = new StringBuilder("select count(*) ");

        Map<String, Object> params = new HashMap<String, Object>();

        KernelClass.spliceSentencesAndPutParams(databaseParameters, wheresql, params);

        countQuery = entityManager.createNativeQuery(countSql.append(from).append(wheresql).toString());

        SqlUtils.setParameters(params,countQuery);
        long count = ((BigInteger) countQuery.getSingleResult()).longValue();
        List<Object> list = new ArrayList<Object>();
        if (count > 0) {
            //判断是否需要排序
            if (orderBy!=null && !orderBy.equals("")){
                wheresql.append(" ORDER BY ").append(orderBy).append(" ");
                if (order !=null && !order.equals("")){
                    wheresql.append(order);
                }
            }

            list = (List<Object>) KernelClass.getresultlist(selectSql,fromsql,wheresql,params,pageable,entityManager,classtype,true);
        }

        return new PageImpl<>(list, pageable, count);
    }

    public static Pageable initPageable(int pageNum, int pageSize){
        Pageable pageable;
        if (pageNum == -1) {
            pageable = PageRequest.of(0, Integer.MAX_VALUE).previous();
        } else {
            pageable = PageRequest.of(pageNum-1, pageSize);
        }
        return pageable;
    }
}
